#ifndef ADV_POSIX_MSGQUEUE_H
#define ADV_POSIX_MSGQUEUE_H

#include <string>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdexcept>

class AdvPOSIXMsgqueue
{
  public:
    AdvPOSIXMsgqueue(const char* queueName);
    virtual ~AdvPOSIXMsgqueue();
    AdvPOSIXMsgqueue& operator<< (const std::string & data);
    AdvPOSIXMsgqueue& operator>> (std::string& data);
    //只支持void和std::string
    template<class RetVal>
    RetVal call (const std::string& data)
    {
      Write(data.data(),data.size());
      if constexpr (std::is_same_v<RetVal,void>)
      {
        return;
      }
      else if constexpr (std::is_same_v<RetVal,std::string>)
      {
        auto size=Read();
        return std::string(receiveBuffer,size);
      }
      else if constexpr (std::is_same_v<RetVal,bool>)
      {
        auto size=Read();
        switch(receiveBuffer[0])
        {
          case 't':
          case 'T':
            return true;
          break;
          case 'f':
          case 'F':
            return false;
          break;
          default:
            throw std::runtime_error("Unknow bool type");
          break;
        }
      }
      else
      {
        //static_assert(false,"无法识别的返回类型");
      }
    }
  private:
    mqd_t queueid;
    char* receiveBuffer;
    std::size_t receiveSize;
    std::size_t Read();
    void Write(const char* data,std::size_t size);

};

#endif
